package ar.edu.utn.frsf.tpae.a2013.g04.service.impl;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import ar.edu.utn.frsf.tpae.a2013.g04.persistence.dao.GastoDAO;
import ar.edu.utn.frsf.tpae.a2013.g04.persistence.dao.SolicitudGastoDAO;
import ar.edu.utn.frsf.tpae.a2013.g04.persistence.model.CentroCosto;
import ar.edu.utn.frsf.tpae.a2013.g04.persistence.model.Empleado;
import ar.edu.utn.frsf.tpae.a2013.g04.persistence.model.Gasto;
import ar.edu.utn.frsf.tpae.a2013.g04.persistence.model.SolicitudGasto;
import ar.edu.utn.frsf.tpae.a2013.g04.service.SolicitudGastoService;
import ar.edu.utn.frsf.tpae.a2013.g04.service.exc.InvalidState;

public class SolicitudGastoServiceImp implements SolicitudGastoService {

	private SolicitudGastoDAO solDAO;
	private GastoDAO gasDAO;

	@Override
	public SolicitudGasto nuevaSolicitudGasto(CentroCosto centro, String descripcion,
			Empleado empleado, Double importe) {
	
		if(centro == null) 
			throw new NullPointerException("centro is null");
		if(empleado == null) 
			throw new NullPointerException("empleado is null");
		if(importe == null) 
			throw new NullPointerException("importe is null");
		
		SolicitudGasto sol = new SolicitudGasto();
		
		Date now= new Date(System.currentTimeMillis());
		sol.setFechaCreacion(now);
		
		sol.setCentroCosto(centro);
		sol.setDescripcion(descripcion);
		sol.setEmpleado(empleado);
		sol.setEstado(SolicitudGasto.PENDIENTE);
		sol.setImporteEstimado(importe);
		solDAO.persistir(sol);
		
		return sol;
	}

	@Override
	public List<SolicitudGasto> listarSolicitudesEmpleado(Empleado empleado) {

		if(empleado == null) 
			throw new NullPointerException("empleado is null");
		
		return solDAO.buscarSolicitudes(empleado);

	}

	@Override
	public Gasto agregarGasto(SolicitudGasto sol, Date fecha, String nroFact,
			Double imp) {
		if(sol == null) 
			throw new NullPointerException("sol is null");
		if(fecha == null) 
			throw new NullPointerException("fecha is null");
		if(imp == null) 
			throw new NullPointerException("imp is null");
		
		if(!SolicitudGasto.APROBADA.equals(sol.getEstado()))
            throw new InvalidState("sol state must be APROBADA");
		
		Gasto gasto = new Gasto();
		gasto.setFecha(fecha);
		gasto.setImporte(imp);
		gasto.setNumeroFactura(nroFact);
		gasto.setSolicitudGasto(sol);
		
		Date now= new Date(System.currentTimeMillis());
		gasto.setFechaCreacion(now);
		
		gasDAO.persistir(gasto);
		return gasto;

	}

	@Override
	public List<SolicitudGasto> listarSolicitudPendientes() {
			return filtrarPendientes(solDAO.listarPendientes());
	}

	@Override
	public List<SolicitudGasto> listarSolicitudPendientes(Empleado emp) {
			return filtrarPendientes(solDAO.buscarSolicitudes(emp));
	}

	private List<SolicitudGasto> filtrarPendientes(
			List<SolicitudGasto> buscarSolicitudes) {
		List<SolicitudGasto> ret = new LinkedList<SolicitudGasto>();
		for(SolicitudGasto sol:buscarSolicitudes){
			if(sol.getEstado().equals(SolicitudGasto.PENDIENTE))
				ret.add(sol);
		}
		return ret;
	}

	@Override
	public List<SolicitudGasto> listarSolicitudPendientes(CentroCosto cco) {
			return filtrarPendientes(solDAO.buscarSolicitudes(cco));
	}

	@Override
	public List<SolicitudGasto> listarSolicitudPendientes(Empleado emp,
			CentroCosto cco) {

		if(emp == null) 
			throw new NullPointerException("emp is null");
		if(cco == null) 
			throw new NullPointerException("cco is null");
		
		return filtrarPendientes(solDAO.buscarSolicitudes(emp, cco));

	}

	@Override
	public SolicitudGasto aprobarSolicitud(SolicitudGasto sol, String comentarios) {
		
		if(!SolicitudGasto.PENDIENTE.equals(sol.getEstado())) 
			throw new InvalidState("sol state must be PENDIENTE");
			
		sol.setEstado(SolicitudGasto.APROBADA);
		
		Date now= new Date(System.currentTimeMillis());
		sol.setFechaAprobacion(now);
		sol.setComentario(comentarios);
		solDAO.persistir(sol);
			
		return sol;
	}

	@Override
	public SolicitudGasto rechazarSolicitud(SolicitudGasto sol, String comentarios) {
		if(!SolicitudGasto.PENDIENTE.equals(sol.getEstado())) 
			throw new InvalidState("sol state must be PENDIENTE");
		
		sol.setEstado(SolicitudGasto.RECHAZADA);
		solDAO.persistir(sol);
			
		return sol;
	}


	/*
	 * GETTERS & SETTERS 
	 */

	public SolicitudGastoDAO getSolicitudGastoDAO() {
		return solDAO;
	}

	@Autowired(required = true)
	public void setSolicitudGastoDAO(SolicitudGastoDAO solDAO) {
		this.solDAO = solDAO;
	}

	public GastoDAO getGastoDAO() {
		return gasDAO;
	}

	@Autowired(required = true)
	public void setGastoDAO(GastoDAO gasDAO) {
		this.gasDAO = gasDAO;
	}

	@Override
	public List<Gasto> buscarGastos() {
		// TODO Auto-generated method stub
		return this.gasDAO.buscarGastos();
	}

	@Override
	public List<Gasto> buscarGastos(Empleado emp, CentroCosto cco) {
		if(emp == null) 
			throw new NullPointerException("emp is null");
		if(cco == null) 
			throw new NullPointerException("cco is null");
		
		return this.gasDAO.buscarGastos(cco, emp);
	}

	@Override
	public List<Gasto> buscarGastos(CentroCosto cco) {

		if(cco == null) 
			throw new NullPointerException("cco is null");
		return this.gasDAO.buscarGastos(cco);
	}

	@Override
	public List<Gasto> buscarGastos(Empleado emp) {
		if(emp == null) 
			throw new NullPointerException("emp is null");
		return this.gasDAO.buscarGastos(emp);
	}

}
